﻿''' <summary>
''' 組織単位リスト画面のフォームです。
''' </summary>
''' <remarks></remarks>
Public Class OUList
  Inherits Page

#Region " プライベートフィールド "
  '直下のオブジェクト格納用(OU自身のパス, 直下のオブジェクトの名前と種類と説明を格納したデータソース用のテーブル)
  Private domainObjectsInfos As Dictionary(Of String, DataTable)
  Private ouCol As List(Of OrganizationalUnit)   'OUのコレクション
#End Region

#Region " イベントハンドラ "
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If MyBase.Page.IsPostBack Then  'ポストバックの時
      domainObjectsInfos = DirectCast(ViewState("domainObjectsInfos"), Dictionary(Of String, DataTable))
      Return
    End If

    Dim ous = DirectoryAccess.GetOrganizationalUnits()  'OUを取得
    ouCol = ous.OrderBy(Function(ou) ou.DisplayPath).ThenBy(Function(ou) ou.Name).ToList()
    Me.CountLabel.Text = String.Format("{0} 個のオブジェクト", ous.Count)

    domainObjectsInfos = New Dictionary(Of String, DataTable)()
    ViewState("domainObjectsInfos") = domainObjectsInfos
    Me.AddChildNode(Nothing)  '子ノードを追加
  End Sub

  Private Sub DetailDataSource_Selecting(
    sender As Object, e As ObjectDataSourceSelectingEventArgs) Handles DetailDataSource.Selecting

    If Me.OUTreeView.SelectedNode Is Nothing Then
      e.Cancel = True
    End If
  End Sub

  Private Sub DetailDataSource_Selected(
    sender As Object, e As ObjectDataSourceStatusEventArgs) Handles DetailDataSource.Selected

    Me.DataPanel.Visible = True
    Me.ShowStoredData(DirectCast(e.ReturnValue, OrganizationalUnit))  '格納されているデータを表示
  End Sub

  Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Response.Redirect("Main.aspx?idx=3")
  End Sub
#End Region

#Region " プライベートメソッド "
  ''' <summary>
  ''' 子ノードを追加します。
  ''' </summary>
  ''' <param name="node">子ノードを追加するノード。</param>
  ''' <remarks></remarks>
  Private Sub AddChildNode(node As TreeNode)
    Dim path = If(node Is Nothing, String.Empty, node.ValuePath)
    Dim childOUs = ouCol.Where(Function(ou) ou.DisplayPath.Equals(path)).ToList()   '直下のOU

    For Each ou In childOUs
      Dim childNode = CreateNode(ou)  'ノードを作成
      If node Is Nothing Then
        Me.OUTreeView.Nodes.Add(childNode)
      Else
        node.ChildNodes.Add(childNode)
      End If
      Me.AddChildNode(childNode)  '子ノードを追加
    Next
  End Sub

  ''' <summary>
  ''' 指定した OU のノードを作成します。
  ''' </summary>
  ''' <param name="ou">OU。</param>
  ''' <returns>作成したノード。</returns>
  ''' <remarks></remarks>
  Private Function CreateNode(ou As OrganizationalUnit) As TreeNode
    Dim path = If(ou.DisplayPath.Length = 0, String.Empty, ou.DisplayPath & "/")
    Return New TreeNode(ou.Name, path & ou.Name)
  End Function

  ''' <summary>
  ''' 指定した OU に格納されているデータを表示します。
  ''' </summary>
  ''' <param name="ou">OU。</param>
  ''' <remarks></remarks>
  Private Sub ShowStoredData(ou As OrganizationalUnit)
    Dim table As DataTable = Nothing
    If domainObjectsInfos.TryGetValue(Me.OUTreeView.SelectedValue, table) = False Then  '直下のオブジェクトを格納していない時
      table = CreateDataSourceTable()   'データソース用のテーブルを作成
      For Each domainObject In ou.StoredDomainObjects   '直下のオブジェクト数分
        Dim row = table.NewRow()
        Dim objectType = DirectCast([Enum].Parse(GetType(CategoryType), domainObject.Entry.SchemaClassName, True), CategoryType)
        row.Item(0) = domainObject.Name   '名前をセット
        row.Item(1) = DirectoryAccess.CategoryNames.Item(objectType)  '種類をセット
        row.Item(2) = domainObject.Description  '説明をセット
        table.Rows.Add(row)
      Next
      domainObjectsInfos.Add(Me.OUTreeView.SelectedValue, table)
    End If

    Me.DataCountLabel.Text = String.Format("{0} 個のオブジェクト", table.Rows.Count)
    Me.DataCountLabel.Visible = table.Rows.Count > 0
    Me.DataGridView.DataSource = table
    Me.DataGridView.DataBind()
  End Sub

  ''' <summary>
  ''' データソース用のテーブルを作成します。
  ''' </summary>
  ''' <returns>データソース用のテーブル。</returns>
  ''' <remarks></remarks>
  Private Function CreateDataSourceTable() As DataTable
    Dim table As New DataTable()
    table.Columns.Add(New DataColumn("Name", GetType(String)))
    table.Columns.Add(New DataColumn("Type", GetType(String)))
    table.Columns.Add(New DataColumn("Description", GetType(String)))
    Return table
  End Function
#End Region
End Class